#include <curses.h> 
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <time.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>

// ASCII Art Definitions
char gameTitle[] = 
        "                                                              "
        "  ,---.   ,--. ,------.      ,--.   ,--.   ,---.   ,------.   "
        " /  O  \\  |  | |  .--. '     |  |   |  |  /  O  \\  |  .--. '  "
        "|  .-.  | |  | |  '--'.'     |  |.'.|  | |  .-.  | |  '--'.'  "
        "|  | |  | |  | |  |\\  \\      |   ,'.   | |  | |  | |  |\\  \\   "
        "`--' `--' `--' `--' '--'     '--'   '--' `--' `--' `--' '--'  "
        "                                                              ";
char gameDeck[1044] = "          _________                   /         \\                 /           \\               /             \\             /               \\           /                 \\         /                   \\       /                     \\     /                       \\   /                         \\ |             |             ||    _   _         _   _    ||    _| | |   |    _| | |   ||   |_  |_|       |_  |_|   ||    _   _    |    _   _    ||   |_  |_|       |_   _|   ||   |_|  _|   |   |_| |_    ||                           ||             |             ||             |             ||                           ||             |             ||             |             ||             |             ||                           ||             |             ||             |             ||             |             ||                           ||             |             ||             |             ||             |             ||                           ||             |             ||             |             ||             |             |";
char playerCraftSprite[43] = 
"   I   "
"  /I\\  "
"  |I|  "
" /\\I/\\ "
"/^^_^^\\"
" --0-- ";
char enemySprite[43] = " --0-- \\  _  / \\/I\\/   |I|    \\I/     I   ";
char enemyDestroyedSprite[43] = " _____ _______ _____   ___    ___     _   ";
char craftDestroyedSprite[43] = "   _     ___    ___   _____ _______ __ __ ";
char readyScreenText[] = 
"                                                "
",------. ,------.  ,---.  ,------.,--.   ,--.   "
"|  .--. '|  .---' /  O  \\ |  .-.  \\\\  `.'  /   "
"|  '--'.'|  `--, |  .-.  ||  |  \\  :'.    /    "
"|  |\\  \\ |  `---.|  | |  ||  '--'  /  |  |     "
"`--' '--'`------'`--' `--'`-------'   `--'     "
"                                                ";
char goScreenText[] = 
"                                            "
" ,---.,--------. ,---.  ,------.,--------.  "
"'   .-'--.  .--'/  O  \\ |  .--. '--.  .--'  "
"`.  `-.  |  |  |  .-.  ||  '--'.'  |  |     "
".-'    | |  |  |  | |  ||  |\\  \\   |  |     "
"`-----'  `--'  `--' `--'`--' '--'  `--'     "
"                                            ";
char pauseMessageText[51] = "PRESS 'P' TO QUIT OR 'A'|'D' TO CONTINUE. ";
char pauseLineText[126] = "---------------------------------------------------";
char gameStateRequestText[20] = "GS";
char scoreRequestText[2] = "SR";
char scoreDisplayText[408] =
" ,----.     ,---.  ,--.   ,--.,------.  "
"'  .-./    /  O  \\ |   `.'   ||  .---'  "
"|  | .---.|  .-.  ||  |'.'|  ||  `--,   "
"'  '--'  ||  | |  ||  |   |  ||  `---.  "
" `------' `--' `--'`--'   `--'`------'  "
" ,-----.,--.   ,--.,------.,------.     "
"'  .-.  '\\  `.'  / |  .---'|  .--. '    "
"|  | |  | \\     /  |  `--, |  '--'.'    "
"'  '-'  '  \\   /   |  `---.|  |\\  \\     "
" `-----'    `-'    `------' `--' '--'    ";


char versusText[] =
" ,--.   ,--.,---.    "
" \\  `.'  /'   .-'   "
"  \\     / `.  `-.   "
"   \\   /  .-'    |  "
"    `-'   `-----'    "
"                     ";
char loseText[] = 
" ,--.     ,-----.   ,---.   ,------.  "
" |  |    '  .-.  ' '   .-'  |  .---'  "
" |  |    |  | |  | `.  `-.  |  `--,   "
" |  '--. '  '-'  ' .-'    | |  `---.  "
" `-----'  `-----'  `-----'  `------'  "
"                                      ";
char winText[] = 
" ,--.   ,--. ,--. ,--.  ,--.  "
" |  |   |  | |  | |  ,'.|  |  "
" |  |.'.|  | |  | |  |' '  |  "
" |   ,'.   | |  | |  | `   |  "
" '--'   '--' `--' `--'  `--'  "
"                              ";
struct Room {
    int roomID;
    int player1FD;
    int player2FD;
    char player1Name[15];
    char player2Name[15];
    int isActive; // 标记房间是否处于活跃状态
    int hasPassword;           // 房间是否有密码（1 = 有, 0 = 无）
    char password[20];         // 房间密码（如果有）
} rooms[100];
// Function Declarations
void executeMenu();
void terminateGame();
void verifyWindowSize();
void verifyColorSupport();
void displaySlantText(char * text, int width, int height, int x, int y, int step, int delay);
void eraseSlantText(int width, int height, int x, int y, int step, int delay);
void renderCharacter(char c, int x, int y);
void renderLogo();
void updateMenuSelection(int selectionType);
void setFontColor(int colorPair, int bold);
void highlightMenuOption(int option, int highlight);
void drawMenu();
void moveCursorToCorner();
void runTest();
void animateButton(char * text, int width, int height, int x, int y, int *delayTimes, int arraySize, int endPosition);
void renderTextOnScreen(char * text, int height, int width, int x, int y);
void renderNonSpaceCharacters(char * text, int height, int width, int x, int y);
void startGame();
void displayReadyMessage();
void controlPlayerCraft(int keyPress);
void clearLeftEdge();
void clearRightEdge();
void initializeGameMap();
int logEntityOnMap(int x, int y, int type);
int randomRange(int max);
void * handleNetworkROOMMessages(void * args);
void spawnNewEnemy();
void updateEnemies();
void showUser();
void updateBullets();
void * mapRefresher(void * args);
void spawnAdditionalEnemy();
void advanceEnemy(int enemyIndex);
void verifyEnemyPosition();
void eraseGameMap();
void applyDamage();
int getMapValue(int x, int y);
void setEnemyMap(int x, int y, int type);
void drawGameEdges();
void * protectPlayerRoutine(void * args);
void verifyBulletPosition();
void displayLifeAndScore();
void spawnBullet();
void listRooms();
void moveBulletUp(int bulletIdx);
void * playerCraftThread(void * args);
void displayPauseScreen();
void removePauseScreen();
void checkLoginStatus();
void * networkFlashRoutine(void * args);
void promptPlayerName();
void retrievePlayerName();
void * findOpponentRoutine(void * args);
void * handleNetworkMessages(void * args);
void promptPassword(char *password);
void updatePlayerScore();
void createRoom();
void joinRoom();
void initnet();
void initializeNetwork();
// Structures for Enemies and Bullets
struct Enemy {
    int health;
    int posX;
    int posY;
} enemies[20];

struct Bullet {
    int damage;
    int posX;
    int posY;
} bullets[20];

// Global Variables with Renamed Identifiers
int enemyPointer = 0;
int enemyLowPointer = 0;
int bulletPointer = 0;
int bulletLowPointer = 0;
int difficulty = 20;
int caseCounter = 0;
int gameActive = 1;
int isProtected = 0;
int flashProtection = 0;
int playerLives = 2;
int playerScore = 0;
int totalTime = 1;
int isPaused = 0;
int menuChoice = 1;
int craftX = 9;
int currentKey = 0;
char playerName[15];
int nameIndex = 0;
int networkStatus = 0;
int socketFD;
struct sockaddr_in serverAddress;
char buffer[1024];
int sessionNumber;
int readyCount = 0;
pthread_t refreshThread;
pthread_t craftMovementThread;
pthread_t networkFlashThread;
pthread_t findOpponentThread;
pthread_t networkInputThread;
pthread_t connectionThread;
pthread_mutex_t writeLock = PTHREAD_MUTEX_INITIALIZER;  // Mutex for write/read synchronization
pthread_mutex_t clearLock = PTHREAD_MUTEX_INITIALIZER;  // Mutex for write/read synchronization
sem_t * gameSemaphore;
sem_t * networkSemaphore;
char opponentName[15];
int tableNumber;

// 定义游戏地图
int gameMap[87][34];
void listRooms(){
    // 发送请求
    char request[] = "LIST_ROOMS\r\n\r\n";
    write(socketFD, request, strlen(request));
    
    // 接收响应
    memset(buffer, 0, sizeof(buffer));
    int bytesRead = read(socketFD, buffer, sizeof(buffer));
    if(bytesRead > 0){
        if(strncmp(buffer, "ROOM_LIST", 9) == 0){
            // 解析并显示房间列表
            mvprintw(35, 54, "Available Rooms:\n");
            char *roomInfo = buffer + 10;
            mvprintw(36, 54, "%s", roomInfo);
            refresh();
        }
        else{
            // 处理其他响应
            mvprintw(35, 54, "Failed to list rooms: %s", buffer);
            refresh();
        }
    }
}

int roomID;
void createRoom(){
    // 清除屏幕上的提示信息
    eraseSlantText(110, 36, 0, 0, 3, 5000);
    setFontColor(0, 1);
    
    // 提示用户是否设置房间密码
    mvprintw(17, 34, "Do you want to set a room password? (y/n): ");
    refresh();
    char choice = getch();
    int hasPassword = 0;
    char password[20] = {0};
    
    if(choice == 'y' || choice == 'Y'){
        hasPassword = 1;
        mvprintw(18, 34, "Enter password (max 19 chars): ");
        refresh();
        echo(); // 开启回显
        getnstr(password, 19);
        noecho(); // 关闭回显
    }
    
    // 发送创建房间请求
    // 请求格式: CREATE_ROOM <playerName> <hasPassword> <password>
    char request[128];
    if(hasPassword){
        sprintf(request, "CREATE_ROOM %s %d %s\r\n\r\n", playerName, hasPassword, password);
    }
    else{
        sprintf(request, "CREATE_ROOM %s %d \r\n\r\n", playerName, hasPassword);
    }
    write(socketFD, request, strlen(request));
    
    // 等待服务器响应
    memset(buffer, 0, sizeof(buffer));
    int bytesRead = read(socketFD, buffer, sizeof(buffer) - 1);
    if(bytesRead > 0){
        buffer[bytesRead] = '\0'; // 确保字符串结束
        
        char responseType[20];
        sscanf(buffer, "%s %d", responseType, &roomID);
        if(strcmp(responseType, "ROOM_CREATED") == 0){
            // 创建房间成功，显示房间ID并等待对手加入
            mvprintw(23,34, "Room created with ID: %d. Waiting for opponent...", roomID);
            refresh();
            
            // 等待服务器通知游戏开始
            while(1){
                memset(buffer, 0, sizeof(buffer));
                bytesRead = read(socketFD, buffer, sizeof(buffer) - 1);
                if(bytesRead > 0){
                    buffer[bytesRead] = '\0'; // 确保字符串结束
                    
                    char gameStartType[20];
                    int receivedRoomID;
                    sscanf(buffer, "%s %d %s", gameStartType, &receivedRoomID, opponentName);
                    if(strcmp(gameStartType, "GAME_START") == 0 && receivedRoomID == roomID){
                        // 游戏开始，显示对战信息
                        eraseSlantText(110, 36, 0, 0, 3, 5000);
                        setFontColor(2, 1);
                        mvprintw(8, 20, "%s", playerName);
                        setFontColor(4, 1);
                        mvprintw(24, 72, "%s", opponentName);
                        moveCursorToCorner();
                        setFontColor(1, 1);
                        displaySlantText(versusText, 20, 5, 41, 14, 1, 5000);
                        sleep(2);
                        playerLives = 2;
                        readyCount = 3;
                        pthread_create(&connectionThread, NULL, handleNetworkROOMMessages, NULL);
                        startGame();
                        
                        break;
                    }
                }
                usleep(100000); // 防止CPU占用过高
            }
        }
        else{
            // 处理错误响应
            mvprintw(35, 54, "Failed to create room: %s", buffer);
            refresh();
        }
    }
    else{
        // 处理读取错误
        mvprintw(35, 54, "Failed to read server response.");
        refresh();
    }
    eraseSlantText(110, 36, 0, 0, 5, 5000);
                    
}

int receivedRoomID;                       
void joinRoom() {
    // 发送 LIST_ROOMS 请求以获取房间列表
    char request[128];
    sprintf(request, "LIST_ROOMS\r\n");
    write(socketFD, request, strlen(request));
    // 接收服务器响应
    char buffer[4096];
    memset(buffer, 0, sizeof(buffer));
    int bytesRead = read(socketFD, buffer, sizeof(buffer) - 1);
    if (bytesRead <= 0) {
        mvprintw(36, 54, "Failed to read server response.");
        refresh();
        return;
    }
    buffer[bytesRead] = '\0';  // 确保字符串结束

    // 解析服务器响应
    if (strncmp(buffer, "ROOM_LIST", 9) == 0) {
        // 跳过 "ROOM_LIST" 部分，开始解析房间信息
        char *line = strtok(buffer + 9, "\n");  // 跳过 "ROOM_LIST\n"

        int totalRooms = 0;
        struct Room rooms[10];  // 假设最大房间数为 MAX_ROOMS

        // 解析每一行房间信息
        while (line != NULL) {
            // 去掉每一行的前后空格
            while (isspace((unsigned char)*line)) line++;  // 去前空格
            char *end = line + strlen(line) - 1;
            while (end > line && isspace((unsigned char)*end)) end--;  // 去后空格
            *(end + 1) = '\0';  // 终止字符串

            if (strlen(line) > 0) {
                int roomID;
                char player1Name[20], passwordStatus[4];

                // 解析房间信息
                int parsed = sscanf(line, "Room ID: %d, Host: %[^,], Password: %[^\n]", 
                     &roomID, player1Name, passwordStatus);
                if (parsed == 3) {
                    rooms[totalRooms].roomID = roomID;
                    strcpy(rooms[totalRooms].player1Name, player1Name);
                    rooms[totalRooms].hasPassword = (strcmp(passwordStatus, "Yes") == 0);
                    rooms[totalRooms].isActive = 1;  // 假设房间是激活的
                    rooms[totalRooms].player2FD = -1;  // 假设没有第二个玩家
                    totalRooms++;
                } else {
                    // 如果解析失败，打印一下行内容，帮助调试
                    printf("Failed to parse line: %s\n", line);
                }
            }

            // 继续处理下一行
            line = strtok(NULL, "\n");
        }

        
        // 显示房间列表，允许用户选择
        int selectedRoom = 0;
        while (1) {
            // 显示房间列表
            for (int i = 0; i < totalRooms; i++) {
                if (i == selectedRoom) {
                    setFontColor(1, 1);  // 高亮显示
                    mvprintw(26 + i, 70, "> Room ID: %d, Host: %s, Password: %s",
                             rooms[i].roomID, rooms[i].player1Name, rooms[i].hasPassword ? "Yes" : "No");
                    setFontColor(0, 0);
                } else {
                    mvprintw(26 + i, 70, "  Room ID: %d, Host: %s, Password: %s",
                             rooms[i].roomID, rooms[i].player1Name, rooms[i].hasPassword ? "Yes" : "No");
                }
            }
            refresh();

            // 获取用户输入
            char key = getch();
            if (key == 'w' || key == 'W') {
                if (selectedRoom > 0) {
                    selectedRoom--;
                }
            } else if (key == 's' || key == 'S') {
                if (selectedRoom < totalRooms - 1) {
                    selectedRoom++;
                }
            } else if (key == '\n') {
                // 用户选择了一个房间，加入房间
                int roomID = rooms[selectedRoom].roomID;
                if (rooms[selectedRoom].hasPassword) {
                    // 如果房间有密码，要求用户输入密码
                    echo();
                    char inputPassword[20] = {0};
                    mvprintw(26 + totalRooms + 1, 70, "Enter password for room %d: ", roomID);
                    refresh();
                    getnstr(inputPassword, 19);
                    noecho();

                    // 发送加入房间请求
                    char joinRequest[128];
                    sprintf(joinRequest, "JOIN_ROOM %d %s %s\r\n\r\n", roomID, playerName, inputPassword);
                    write(socketFD, joinRequest, strlen(joinRequest));
                } else {
                    // 如果房间没有密码，直接加入
                    char joinRequest[128];
                    sprintf(joinRequest, "JOIN_ROOM %d %s 0\r\n\r\n", roomID, playerName);
                    write(socketFD, joinRequest, strlen(joinRequest));
                }

                // 等待服务器的响应
                memset(buffer, 0, sizeof(buffer));
                int responseLength = read(socketFD, buffer, sizeof(buffer) - 1);
                if (responseLength > 0) {
                    buffer[responseLength] = '\0';  // 确保字符串结束
                    
                    // 处理服务器的响应
                    if (strncmp(buffer, "GAME_START", 10) == 0) {
                        
                        // 游戏开始，解析房间信息
                        char gameStartType[20];
                        
                        char opponentName[15];
                        sscanf(buffer, "%s %d %s", gameStartType, &receivedRoomID, opponentName);
                        if (strcmp(gameStartType, "GAME_START") == 0 && receivedRoomID == roomID) {
                            // 游戏开始，显示对战信息
                            eraseSlantText(110,80, 0, 0, 5, 5000);
                    
                            setFontColor(2, 1);
                            mvprintw(8, 20, "%s", playerName);
                            setFontColor(4, 1);
                            mvprintw(24, 72, "%s", opponentName);
                            moveCursorToCorner();
                            setFontColor(1, 1);
                            displaySlantText(versusText, 20, 5, 41, 14, 1, 5000);
                            sleep(2);
                            playerLives = 3;
                            readyCount = 3;
                            pthread_create(&connectionThread, NULL, handleNetworkROOMMessages, NULL);
                            startGame();
                        }
                    } else if (strncmp(buffer, "ERROR", 5) == 0) {
                        // 处理错误响应
                        mvprintw(35 + totalRooms + 2, 54, "%s", buffer);
                        eraseSlantText(110, 36, 0, 0, 5, 5000);
                        drawMenu();
                        refresh();
                    } else {
                        mvprintw(35 + totalRooms + 2, 54, "Unexpected response: %s", buffer);
                        eraseSlantText(110, 36, 0, 0, 5, 5000);
                        drawMenu();
                        refresh();
                    }
                } else {
                    mvprintw(35 + totalRooms + 2, 54, "Failed to read server response.");
                    eraseSlantText(110, 36, 0, 0, 5, 5000);
                    drawMenu();
                    refresh();
                }
                break;  // 退出选择循环
            }
        }
    } else {
        mvprintw(36, 54, "Unexpected server response: %s", buffer);
        refresh();
    }
    eraseSlantText(110, 36, 0, 0, 5, 5000);
                    
}

void *handleNetworkROOMMessages(void *args) {
    char recvBuffer[128];
    char messageHeader[10];
    char messageText[128];
    char request[128];
    
    while (1) {
        // 检查玩家是否输掉
        if (playerLives <= 0) {
            // 向服务器发送失败消息
            sprintf(request, "DQ %d", roomID);
            write(socketFD, request, sizeof(request));
            close(socketFD);  // 关闭连接
            sleep(3);
            break;  // 退出线程
        } else {
            // 向服务器发送玩家生命状态
            sprintf(request, "AL %d", roomID);
            write(socketFD, request, sizeof(request));
            
            // 接收服务器的回应
            sessionNumber = read(socketFD, recvBuffer, sizeof(recvBuffer));
            sscanf(recvBuffer, "%s %s", messageHeader, messageText);
            
            // 处理服务器返回的胜利消息
            if (strcmp(messageHeader, "WI") == 0) {
                isPaused = 1;  // 暂停游戏
                eraseSlantText(110, 36, 0, 0, 3, 5000);  // 清屏
                displaySlantText(winText, 30, 6, 47, 15, 5, 5000);  // 显示胜利文本
                readyCount = 0;  // 重置准备状态
                close(socketFD);  // 关闭连接
                sleep(3);
                playerLives = 0;  // 重置玩家生命值
                eraseSlantText(110, 36, 0, 0, 5, 5000);
                drawMenu();  // 绘制菜单
                break;  // 退出线程
            }
        }
        usleep(100000);  // 防止 CPU 占用过高
    }
    return NULL;
}


//检查胜利或失败并返回
void * handleNetworkMessages(void * args){
    char recvBuffer[128];
    char messageHeader[10];
    char messageText[128];
    char request[128];
    while(1){
        if(playerLives <= 0){
            sprintf(request, "DI %d", tableNumber);
            write(socketFD, request, sizeof(request));
            close(socketFD);
            sleep(3);
            break;
        } else {
            sprintf(request, "AL %d", tableNumber);
            write(socketFD, request, sizeof(request));
            sessionNumber = read(socketFD, recvBuffer, sizeof(recvBuffer));
            sscanf(recvBuffer, "%s%s", messageHeader, messageText);
            if(strcmp(messageHeader, "WI") == 0){
                isPaused = 1;
                eraseSlantText(110, 36, 0, 0, 5, 5000);
                displaySlantText(winText, 30, 6, 47, 15, 5, 5000);  // 显示胜利文本
                readyCount = 0;
                close(socketFD);
                sleep(3);
                playerLives = 0;
                eraseSlantText(110, 36, 0, 0, 5, 5000);
                drawMenu();
                break;
            }
        }
        usleep(100000);	
    }
    return NULL;
}

// 玩家输入退出则线程一直进行
void * captureNetworkCharacters(void * args){
    while(currentKey != 'P' && currentKey != 'p' && readyCount != 3){
        currentKey = getch();
    }
    readyCount = 0;
    sem_post(networkSemaphore);
    return NULL;
}

// 刷新网络状态显示
void * networkFlashRoutine(void * args){
    int toggle = 1;
    while(readyCount == 1){
        if(toggle == 1){
            setFontColor(1, 0);
            mvprintw(28, 41, "Network Game");
        } else {
            setFontColor(1, 1);
            mvprintw(28, 41, "Network Game");
        }
        moveCursorToCorner();
        refresh();
        usleep(500000);
        toggle = -toggle;		
    }
    setFontColor(1, 1);
    mvprintw(28, 41, "Network Game");
    moveCursorToCorner();
    refresh();
    return NULL;
}
char storedName[15], storedPassword[15], storedScore[10];
// 修改后的检查并显示登录状态函数
void checkLoginStatus() {
    playerName[0] = 0;  // 清空玩家昵称
    char password[15] = {0};    
    char line[50];

                
    // 如果文件存在，读取并验证
    if (access("Data.txt", F_OK) == 0) {
        FILE *filePtr = fopen("Data.txt", "r");
        if (filePtr != NULL) {
            int found = 0;

            // 读取每一行
            while (fgets(line, sizeof(line), filePtr)) {
                
                // 从每行中提取玩家昵称、密码和最高分
                sscanf(line, "%s %s %s", storedName, storedPassword, storedScore);
                if (playerName[0] == 0) {
                    promptPlayerName();
                }

                // 检查输入的昵称是否与存储的匹配
                if (strcmp(storedName, playerName) == 0) {
                    found = 1;
                    
                    // 密码验证循环，直到用户输入正确密码
                    while (1) {
                        mvprintw(28, 50, "Please Enter Your Password");
                        moveCursorToCorner();
                        refresh();
                        memset(password, 0, sizeof(password));  // 清空密码数组

                        // 输入密码的循环
                        int passwordIndex = 0;
                        while (passwordIndex < 15) {
                            currentKey = getch();
                            if (currentKey == '\n') break;  // 输入完成
                            if (currentKey == 127 && passwordIndex > 0) {  // Backspace
                                password[--passwordIndex] = '\0';
                                mvprintw(29,51, "%-15s", password);  // 更新已输入的密码显示
                            } else if ((currentKey >= 'A' && currentKey <= 'Z') || (currentKey >= 'a' && currentKey <= 'z')) {
                                password[passwordIndex++] = currentKey;
                                mvprintw(29,51, "%-15s", password);  // 更新已输入的密码显示
                            }
                        }

                        // 验证密码
                        if (strcmp(password, storedPassword) == 0) {
                            mvprintw(30,50, "Login successful!");
                            moveCursorToCorner();
                            refresh();
                            sleep(1);
                            break; // 密码正确，退出循环
                        } else {
                            mvprintw(30,50, "Incorrect Password! Try Again");
                            moveCursorToCorner();
                            refresh();
                            sleep(1);
                            // 清空密码输入区域并重新输入
                            memset(password, 0, sizeof(password));  // 清空密码数组
                            passwordIndex = 0; // 重置密码输入索引
                            mvprintw(29,51, "                 ");  // 清空已输入的密码显示
                            mvprintw(30,50, "                                  "); // 清空错误信息
                        }
                    }
                }
            }

            // 如果没有找到玩家，进行注册
            if (!found) {
                mvprintw(26,50, "New player, please register!");
                sleep(1);
                moveCursorToCorner();
                refresh();
                promptPassword(password);  // 提示输入密码

                // 将新玩家的信息写入文件
                int fileDesc = open("Data.txt", O_WRONLY | O_CREAT | O_APPEND, 0644);
                dprintf(fileDesc, "%s %s %s\n", playerName, password, "0");  // 默认最高分为 0
                close(fileDesc);
            }

            fclose(filePtr);
        }
    }

    // 清理显示区域
    mvprintw(26,50, "                                  ");
    mvprintw(27,50, "                                  ");
    mvprintw(28,50, "                                  ");
    mvprintw(29,50, "                                  ");
    mvprintw(30,50, "                                  ");
    mvprintw(31,50, "                                  ");

    // 如果没有设置玩家名字，提示用户输入
    if (playerName[0] == 0) {
        promptPlayerName();
    } else {
        showUser();
        }
}
void showUser(){
    char line[50];
    // 如果文件存在，读取并验证
    if (access("Data.txt", F_OK) == 0) {
        FILE *filePtr = fopen("Data.txt", "r");
        if (filePtr != NULL) {
            int found = 0;
    setFontColor(2, 1);
        while (fgets(line, sizeof(line), filePtr)) {
                char storedName[15], storedPassword[15], storedScore[10];
                // 从每行中提取玩家昵称、密码和最高分
                sscanf(line, "%s %s %s", storedName, storedPassword, storedScore);
                if (playerName[0] == 0) {
                    promptPlayerName();
                }

                // 检查输入的昵称是否与存储的匹配
                if (strcmp(storedName, playerName) == 0) {
        mvprintw(0, 105 - strlen(playerName), "USER:%s", playerName);
        mvprintw(1, 105 - strlen(storedScore)-9, "HightestScore:%s", storedScore);
        moveCursorToCorner();
        refresh();
    }}}}

}
// 修改后的 promptPlayerName 函数，确保玩家昵称被正确绑定
void promptPlayerName() {
    setFontColor(0, 1);
    mvprintw(26,50, "Please Enter Your Name");
    moveCursorToCorner();
    refresh();
    int continuePrompt = 1;
    while (continuePrompt) {
        currentKey = getch();
        if (currentKey == '\n') {
            if (nameIndex == 0) {
                setFontColor(4, 1);
                mvprintw(26,50, "Please Enter Your Name");
                moveCursorToCorner();
                refresh();
                usleep(200000);
                setFontColor(0, 1);
                mvprintw(26,50, "Please Enter Your Name");
                moveCursorToCorner();
                refresh();
            } else {    
                // 在这里保存玩家昵称到 `playerName` 中
                // 防止覆盖之前的输入
                playerName[nameIndex] = '\0';  // 确保字符串结束
                continuePrompt = 0;  // 退出循环
                moveCursorToCorner();
                refresh();
            }
        } else if (currentKey == 127) {
            if (nameIndex > 0) {
                nameIndex -= 1;
                playerName[nameIndex] = '\0';            
                mvprintw(27,51, "%-15s", playerName);
                moveCursorToCorner();
            }
        } else if ((currentKey >= 'A' && currentKey <= 'Z') || (currentKey >= 'a' && currentKey <= 'z') || (currentKey >= '0' && currentKey <= '9')) {
            if (nameIndex <= 14) {
                playerName[nameIndex] = currentKey;
                nameIndex++;
                mvprintw(27,51, "%s", playerName);
            }        
        }
    }
}


void promptPassword(char *password){
    int passwordIndex = 0;
    mvprintw(28,50, "Please Enter Your Password");
    moveCursorToCorner();
    refresh();
    while(passwordIndex < 15){
        currentKey = getch();
        if(currentKey == '\n') break;
        if(currentKey == 127 && passwordIndex > 0){  // Backspace
            password[--passwordIndex] = '\0';
            mvprintw(29,51, "%-15s", password);
        } else if(currentKey >= 'A' && currentKey <= 'Z' || currentKey >= 'a' && currentKey <= 'z') {
            password[passwordIndex++] = currentKey;
            mvprintw(29,51, "%-15s", password);
        }
    }
    
    moveCursorToCorner();
}


// 从文件中读取玩家昵称
void retrievePlayerName(){
    playerName[0] = 0;
    if(access("Data.txt", F_OK) == 0){
        FILE *filePtr = fopen("Data.txt", "r");
        if(filePtr != NULL){
            char line[50];
            while(fgets(line, sizeof(line), filePtr)) {
                char storedName[15], storedPassword[15], storedScore[10];
                // 从每行中提取玩家昵称、密码和最高分
                sscanf(line, "%s %s %s", storedName, storedPassword, storedScore);
                if(strcmp(storedName, playerName) == 0){
                    // 读取并设置玩家数据
                    // 在此，你可以存储玩家的密码和最高分，或其他信息
                    fclose(filePtr);
                    return;
                }
            }
            fclose(filePtr);
        }
    }
}


// 执行菜单选项
void executeMenu(){
    if(menuChoice == 1){
        startGame();
    } else if(menuChoice == 2){
        mvprintw(35, 54, "Looking For Opponents... PRESS 'P' to quit");
        initializeNetwork();
    } else if(menuChoice == 5){
        eraseSlantText(110, 50, 0, 0, 5, 5000);
        mvprintw(0, 70, "                          ");
        
        nameIndex = 0;
        for(int i = 0; i <= 14; i++){
            playerName[i] = '\0';
        }
        displaySlantText(gameTitle,62, 6, 35, 12, 3, 10000);
        setFontColor(0, 1);
        
        mvprintw(29, 39, "%s", playerName);
        checkLoginStatus();
        menuChoice = 1;
        highlightMenuOption(1, (menuChoice == 1) ? 1 : 0);
        highlightMenuOption(2, (menuChoice == 2) ? 1 : 0);
        highlightMenuOption(3, (menuChoice == 3) ? 1 : 0);
        highlightMenuOption(4, (menuChoice == 4) ? 1 : 0);
        highlightMenuOption(5, (menuChoice == 5) ? 1 : 0); // 新增选项
        highlightMenuOption(6, (menuChoice == 6) ? 1 : 0); // 新增选项
        moveCursorToCorner();
        refresh();
    } else if(menuChoice == 6){
        terminateGame();
    }else if(menuChoice == 3){
        initnet();
        createRoom(); // 实现创建房间的函数
    } else if(menuChoice == 4){
        initnet();
        joinRoom(); // 实现加入房间的函数
    }
}
void initnet(){
    sem_init(networkSemaphore, 0, 0);
    if((socketFD = socket(AF_INET, SOCK_STREAM, 0)) == -1){
        setFontColor(4, 1);
        mvprintw(35, 60, "Error: Cannot Build Socket.         ");
        setFontColor(1, 1);
        refresh();
        return;
    }
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_port = htons(8081);
    serverAddress.sin_addr.s_addr = inet_addr("192.168.140.43");

    if(connect(socketFD, (const struct sockaddr *)&serverAddress, sizeof(struct sockaddr_in)) == -1){
        setFontColor(4, 1);
        mvprintw(35, 60, "Error: Cannot Connect to the Server.");
        setFontColor(1, 1);
        refresh();
        return;
    }
}
// 初始化网络连接
void initializeNetwork() {
    char recvBuffer[128];
    char messageHeader[10];
    char messageText[128];
    // 初始化网络连接
    initnet();
    readyCount = 1;
    // 通过轮询的方式处理网络和键盘输入
    while (readyCount != 3) {
        // 发送游戏状态请求
        if (readyCount == 1) {
            char gameStateReq[20];
            sprintf(gameStateReq, "GS %s", playerName);
            write(socketFD, gameStateReq, sizeof(gameStateReq));
        }

        // 发送准备请求
        if (readyCount == 2) {
            char request[128];
            sprintf(request, "RD %d", atoi(messageText));
            write(socketFD, request, sizeof(request));
        }
        // 等待并接收服务器消息
        sessionNumber = read(socketFD, recvBuffer, sizeof(recvBuffer));
        sscanf(recvBuffer, "%s%s", messageHeader, messageText);
        // 收到游戏匹配信息（PG），设置为准备状态
        if (recvBuffer[0] == 'P' && recvBuffer[1] == 'G') {
            readyCount = 2;
        }
        // 收到游戏开始信号（SG），开始游戏
        else if (recvBuffer[0] == 'S' && recvBuffer[1] == 'G') {
            readyCount = 3;
            sscanf(recvBuffer, "%s%d%s", messageHeader, &tableNumber, opponentName);

            // 确保游戏只开始一次
            if (readyCount == 3) {
                eraseSlantText(110, 36, 0, 0, 3, 5000);
                setFontColor(2, 1);
                mvprintw(8, 20, "%s", playerName);
                setFontColor(4, 1);
                mvprintw(24, 72, "%s", opponentName);
                moveCursorToCorner();
                setFontColor(1, 1);
                displaySlantText(versusText,20, 5, 41, 14, 1, 5000);
                sleep(2);
                playerLives = 2;

                // 在此启动游戏
                pthread_create(&connectionThread, NULL, handleNetworkMessages, NULL);
                startGame();
            }
            break;  // 一旦游戏开始，跳出循环
        }

        usleep(100000);  // 防止 CPU 占用过高
    }

    mvprintw(35, 54, "                                          ");
}


// 开始游戏
void startGame(){
    eraseSlantText(110, 36, 0, 0, 5, 5000);
    int sleepTimes[9] = {1000000, 800000, 500000, 300000, 230000, 180000, 130000, 110000, 70000};
    int mapHeight = 36;
    int mapWidth = 29;
    int startX = 5;
    int currentY = 0;
    int sleepArraySize = 9;
    int k, l;

    moveCursorToCorner();
    refresh();
    sleep(1);
    int buttonSleep[1] = {250000};
    animateButton(playerCraftSprite, 6, 7, 9, 25, buttonSleep, 1, 29);
    sleep(1);
    initializeGameMap();
    usleep(500000);
    drawGameEdges();
    usleep(1000);
    displayReadyMessage();
    logEntityOnMap(9, 28, -1);
    pthread_create(&refreshThread, NULL, mapRefresher, NULL);
    pthread_create(&craftMovementThread, NULL, playerCraftThread, NULL);
    
    while(1){
        sem_wait(gameSemaphore);
        if(playerLives <= 0){
            while(flashProtection != 0){
                if(flashProtection % 2 != 0){
                    eraseText(craftDestroyedSprite, 6, 7, craftX, 28);
                } else {
                    renderNonSpaceCharacters(playerCraftSprite,6,7, craftX, 28);
                }
                flashProtection--;
                refresh();
                usleep(100000);
            }
            eraseSlantText(110, 36, 0, 0, 5, 5000);
            setFontColor(1, 1);
            if(readyCount != 3){
                displaySlantText(scoreDisplayText,40,10,35, 10, 5, 5000);
                mvprintw(26, 44, "YOUR SCORE: %10d", playerScore);
                updatePlayerScore();
            } else {
                displaySlantText(loseText,38, 6,47, 15, 5, 5000);
                readyCount = 0;
            }
            moveCursorToCorner();
            refresh();
            sleep(3);
            eraseSlantText(110, 36, 0, 0, 5, 5000);
            drawMenu();
        } else if(isPaused == 1){
            int resume = 1;
            displayPauseScreen();
            while(resume){
                currentKey = getch();
                if(currentKey == 'P' || currentKey == 'p'){
                    resume = 0;
                    eraseSlantText(110, 50, 0, 0, 5, 5000);
                    displaySlantText(scoreDisplayText,40,10,35, 10, 5, 5000);
                    mvprintw(26, 44, "YOUR SCORE: %10d", playerScore);
                    moveCursorToCorner();
                    refresh();
                    sleep(3);
                    eraseSlantText(110, 36, 0, 0, 5, 5000);
                    drawMenu();
                } else if(currentKey == 'a' || currentKey == 'A' || currentKey == 'd' || currentKey == 'D' || currentKey == 's' || currentKey == 'S' || currentKey == 'w' || currentKey == 'W'){
                    if(playerLives == 0) return;
                    resume = 0;
                    removePauseScreen();
                    isPaused = 0;
                    controlPlayerCraft(currentKey);
                    usleep(2000);
                    pthread_create(&refreshThread, NULL, mapRefresher, NULL);
                    pthread_create(&craftMovementThread, NULL, playerCraftThread, NULL);
                }
            }
        }
    }
    eraseSlantText(110, 36, 0, 0, 5, 5000);
}
void updatePlayerScore() {
    FILE *filePtr = fopen("Data.txt", "r");  // 打开文件用于读取
    FILE *tempFile = fopen("tempData.txt", "w");  // 创建临时文件用于写入

    if (filePtr != NULL && tempFile != NULL) {
        char line[50];
        int found = 0;
         while (fgets(line, sizeof(line), filePtr)) {
            char storedName[15], storedPassword[15];
            int storedScoreInt;
            // 从每行中提取玩家昵称、密码和分数
            int parsed = sscanf(line, "%s %s %d", storedName, storedPassword, &storedScoreInt);
            
            if (parsed < 3) {
                // 如果解析失败，保持原样写入
                fprintf(tempFile, "%s\n", line);
                continue;
            }

            // 如果找到玩家，更新其分数
            if (strcmp(storedName, playerName) == 0 && playerScore > storedScoreInt) {
                found = 1;
                // 写入更新后的玩家数据到临时文件
                fprintf(tempFile, "%s %s %d\n", playerName, storedPassword, playerScore);
            } else {
                // 将原文件中其他玩家数据写入临时文件
                fprintf(tempFile, "%s %s %d\n", storedName, storedPassword, storedScoreInt);
            }
        }
        
        // 关闭文件
        fclose(filePtr);
        fclose(tempFile);

        // 删除原文件
        remove("Data.txt");

        // 将临时文件重命名为原文件名
        rename("tempData.txt", "Data.txt");
    } else {
        mvprintw(32, 34, "Error opening file to update score!");
        moveCursorToCorner();
        refresh();
    }
}


//游戏暂停
void displayPauseScreen(){
    setFontColor(1, 1);
    displaySlantText(pauseMessageText, 51, 1, 19, 27, 3, 10000);
}

// 取消暂停
void removePauseScreen(){
    setFontColor(0, 0);
    eraseSlantText(51, 1, 19, 27, 3, 10000);
}

// 飞船响应输入
void * playerCraftThread(void * args){
    while(playerLives > 0 && isPaused != 1){
        currentKey = getch();
        if(playerLives == 0) return NULL;
        if(currentKey == 'a' || currentKey == 'A' || currentKey == 'd' || currentKey == 'D'){
            controlPlayerCraft(currentKey);
        } else if((currentKey == 'P' || currentKey == 'p') && readyCount != 3){
            isPaused = 1;
            sem_post(gameSemaphore);
        }
    }
    return NULL;
}

// 显示生命值以及分数
void displayLifeAndScore(){
    setFontColor(1, 1);
    mvprintw(18, 95, "LIFE: %d", playerLives);
    mvprintw(24, 95, "SCORE %d", playerScore);
    moveCursorToCorner();
}

// 绘制游戏边框
void drawGameEdges(){
    int i;
    setFontColor(0, 1);
    for(i = 0; i <= 44; i++){
        renderCharacter('-', 2 * i, 34);
        renderCharacter('-', 2 * i + 1, 34);
        if(i < 34) renderCharacter('|', 89, i);
        moveCursorToCorner();
        refresh();
        usleep(7000);
    }
    renderCharacter('-', 86, 34);
    renderCharacter('-', 87, 34);
    renderCharacter('-', 88, 34);
    renderCharacter('-', 89, 34);
}

//地图刷新线程
void * mapRefresher(void * args){
    int iteration = 0;
    while(playerLives > 0 && isPaused != 1){
        pthread_mutex_lock(&writeLock);
        if(gameActive == 1){
            spawnNewEnemy();
            updateEnemies();
            spawnBullet();
            updateBullets();
        } else {
            updateBullets();
        }
        setFontColor(3, 1);
        if(flashProtection != 0){
            if(flashProtection % 2 != 0){
                eraseText(craftDestroyedSprite,1, 1, craftX, 28);
            } else {
                renderNonSpaceCharacters(playerCraftSprite, 6,7, craftX, 28);
            }
            flashProtection--;
            if(flashProtection == 0) isProtected = 0;
        } else {
            renderNonSpaceCharacters(playerCraftSprite,6,7, craftX, 28);
        }
        displayLifeAndScore();
        refresh();
        gameActive = -gameActive;
        iteration++;
        pthread_mutex_unlock(&writeLock);
        usleep(100000);
    }
    return NULL;
}

// 生成子弹
void spawnBullet(){
    if(getMapValue(craftX + 3, 28) > 0){
        enemies[getMapValue(craftX + 3, 28) - 1].health -= 1;
        if(enemies[getMapValue(craftX + 3, 28) - 1].health == 0 && enemies[getMapValue(craftX + 3, 28) - 1].health + 1 >= 0){
            eraseText(enemyDestroyedSprite, 6, 7, enemies[getMapValue(craftX + 3, 28) - 1].posX, enemies[getMapValue(craftX + 3, 28) - 1].posY);
            playerScore += 5;
        }
        return;
    }
    bullets[bulletPointer].damage = 1;
    bullets[bulletPointer].posX = craftX + 3;
    bullets[bulletPointer].posY = 28;
    bulletPointer = (bulletPointer == 19) ? 0 : bulletPointer + 1; 
}

// 根据时间生成新敌人
void spawnNewEnemy(){
    if(randomRange(20) + 1 < caseCounter){
        spawnAdditionalEnemy();
        caseCounter = -5;
    } else {
        caseCounter += (caseCounter < 0) ? 1 : difficulty;
    }
}

//生成额外敌人
void spawnAdditionalEnemy(){
    enemies[enemyPointer].health = 3;
    enemies[enemyPointer].posX = randomRange(60);
    enemies[enemyPointer].posY = 0;
    enemyPointer = (enemyPointer == 19) ? 0 : enemyPointer + 1; 
}

// 更新敌人位置
void updateEnemies(){
    eraseGameMap();
    logEntityOnMap(craftX, 28, -2);
    int index = enemyLowPointer;
    while(index != enemyPointer){
        advanceEnemy(index);
        index = (index == 19) ? 0 : index + 1;
    }
}

// 更新子弹的位置
void updateBullets(){
    int index = bulletLowPointer;
    while(index != bulletPointer){
        moveBulletUp(index);
        index = (index == 19) ? 0 : index + 1;
    }
}

void moveBulletUp(int bulletIdx){
    renderCharacter(' ', bullets[bulletIdx].posX, bullets[bulletIdx].posY);
    if(bullets[bulletIdx].damage == 0){
        verifyBulletPosition();
        return;
    }
    if(bullets[bulletIdx].posY == 0){
        renderCharacter(' ', bullets[bulletIdx].posX, bullets[bulletIdx].posY);
        bullets[bulletIdx].damage = 0;
        verifyBulletPosition();
        return;
    }
    // 检查子弹前一行是否有敌机
    int enemyType = getMapValue(bullets[bulletIdx].posX, bullets[bulletIdx].posY - 1);
    if(enemyType > 0){
        // 确保敌机索引在合法范围内
        int enemyIdx = enemyType - 1;
        if(enemyIdx >= 0 && enemyIdx < 20){
            enemies[enemyIdx].health -= bullets[bulletIdx].damage;
            if(enemies[enemyIdx].health <= 0 && enemies[enemyIdx].health + bullets[bulletIdx].damage > 0){
                eraseText(enemyDestroyedSprite, 6, 7, enemies[enemyIdx].posX, enemies[enemyIdx].posY);
                playerScore += 5;
                // 清除地图上的敌机标记
                setEnemyMap(enemies[enemyIdx].posX, enemies[enemyIdx].posY, 0);
            }
        }
        bullets[bulletIdx].damage = 0;
    } else {
        bullets[bulletIdx].posY--;
        setFontColor(3, 0);
        renderCharacter('*', bullets[bulletIdx].posX, bullets[bulletIdx].posY);
        renderCharacter(' ', bullets[bulletIdx].posX, bullets[bulletIdx].posY + 1);
    }
}


// 使敌人前进
void advanceEnemy(int enemyIdx){
    if(enemies[enemyIdx].health <= 0){
        verifyEnemyPosition();
        return;
    }
    if(enemies[enemyIdx].posY == 34){
        enemies[enemyIdx].health = 0;
        verifyEnemyPosition();
        return;
    }
    int i;
    for(i = 0; i < 7; i++){
        renderCharacter(' ', enemies[enemyIdx].posX + i, enemies[enemyIdx].posY);
    }
    if(enemies[enemyIdx].posY + 1 <= 33){
        renderCharacter(' ', enemies[enemyIdx].posX, enemies[enemyIdx].posY + 1);
        renderCharacter(' ', enemies[enemyIdx].posX + 6, enemies[enemyIdx].posY + 1);
    }
    enemies[enemyIdx].posY++;
    if(logEntityOnMap(enemies[enemyIdx].posX, enemies[enemyIdx].posY, enemyIdx) == 2){
        eraseText(loseText,38, 6, 47,15); // Adjusted parameters
        applyDamage();
        enemies[enemyIdx].health = 0;
        return;
    }
    pthread_mutex_lock(&clearLock);
    setFontColor(4, 1);
    renderNonSpaceCharacters(enemySprite,6,7, enemies[enemyIdx].posX, enemies[enemyIdx].posY);
    pthread_mutex_unlock(&clearLock);
}

// 对玩家造成伤害
void applyDamage(){
    if(isProtected == 1){
        return;
    } else if(isProtected == 0){
        playerLives--;
        if(playerLives == 0) sem_post(gameSemaphore);
        isProtected = 1;
        flashProtection = 8;
    }
}

//无敌时间
void * protectPlayerRoutine(void * args){
    for(int u = 0; u <= 4; u++){
        pthread_mutex_lock(&clearLock);
        eraseText(craftDestroyedSprite,1,1, craftX, 28);
        pthread_mutex_unlock(&clearLock);
        usleep(100000);
        pthread_mutex_lock(&clearLock);
        setFontColor(1, 1);
        renderNonSpaceCharacters(playerCraftSprite,1,1, craftX, 28);
        pthread_mutex_unlock(&clearLock);
        usleep(100000);		
    }
    isProtected = 0;
    return NULL;
}

// 验证敌人的指针位置
void verifyEnemyPosition(){
    while(enemies[enemyLowPointer].health <= 0){
        enemyLowPointer = (enemyLowPointer == 19) ? 0 : enemyLowPointer + 1; 	
    }
}

// 验证子弹的指针位置
void verifyBulletPosition(){
    while(bullets[bulletLowPointer].damage == 0){
        bulletLowPointer = (bulletLowPointer == 19) ? 0 : bulletLowPointer + 1; 	
    }
}

// 生成随机数
int randomRange(int max){
    return rand() % max;
}

// 初始化游戏地图
void initializeGameMap(){
    pthread_mutex_unlock(&writeLock);
    pthread_mutex_unlock(&clearLock);
    sem_init(gameSemaphore, 0, 0);
    playerLives = 2;
    playerScore = 0;
    isPaused = 0;
    totalTime = 0;
    gameActive = 1;
    caseCounter = 0;
    flashProtection = 0;
    craftX = 9;
    isProtected = 0;
    int xx = 0;
    int yy = 0;
    eraseGameMap();
    for(xx = 0; xx < 20; xx++){
        bullets[xx].posX = 0;
        bullets[xx].posY = 0;
        bullets[xx].damage = 0;
        enemies[xx].posX = 0;
        enemies[xx].posY = 0;
        enemies[xx].health = 0;
    }
    enemyPointer = 0;
    enemyLowPointer = 0;
    bulletPointer = 0;
    bulletLowPointer = 0;
}

// 清空整个游戏地图
void eraseGameMap(){
    int mx, my;
    for(mx = 0; mx <= 82; mx++){
        for(my = 0; my <= 33; my++){
            gameMap[mx][my] = 0;
        }
    }
}

// 根据键盘输入移动玩家飞船
void controlPlayerCraft(int keyPress){
    pthread_mutex_lock(&writeLock);
    setFontColor(3, 1);
    int i;
    if(keyPress == 'D' || keyPress == 'd'){
        if(craftX == 82){
            pthread_mutex_unlock(&writeLock);
            return;
        }
        clearLeftEdge();
        craftX += 1;
    } else if(keyPress == 'A' || keyPress == 'a'){
        if(craftX == 0){
            pthread_mutex_unlock(&writeLock);
            return;
        }
        clearRightEdge();
        craftX -= 1;
    }
    logEntityOnMap(craftX, 28, -1);
    if(!(flashProtection != 0 && flashProtection % 2 == 0)) {
        renderNonSpaceCharacters(playerCraftSprite,6,7, craftX, 28);
    }
    moveCursorToCorner();
    pthread_mutex_unlock(&writeLock);
}

// 在地图上记录实体位置
int logEntityOnMap(int xPos, int yPos, int type){
    if(type == -1){
        clearCraftMap(xPos + 3, yPos);
        clearCraftMap(xPos + 2, yPos + 1);
        clearCraftMap(xPos + 4, yPos + 1);
        clearCraftMap(xPos + 2, yPos + 2);
        clearCraftMap(xPos + 4, yPos + 2);
        clearCraftMap(xPos + 1, yPos + 3);
        clearCraftMap(xPos + 5, yPos + 3);
        clearCraftMap(xPos + 0, yPos + 4);
        clearCraftMap(xPos + 6, yPos + 4);
    } else if(type == -2){
        gameMap[xPos + 3][yPos] = -1;
        gameMap[xPos + 2][yPos + 1] = -1;
        gameMap[xPos + 4][yPos + 1] = -1;
        gameMap[xPos + 2][yPos + 2] = -1;
        gameMap[xPos + 4][yPos + 2] = -1;
        gameMap[xPos + 1][yPos + 3] = -1;
        gameMap[xPos + 5][yPos + 3] = -1;
        gameMap[xPos + 0][yPos + 4] = -1;
        gameMap[xPos + 6][yPos + 4] = -1;
    } else {
        type++;
        if(getMapValue(xPos, yPos + 1) + getMapValue(xPos + 6, yPos + 1) + getMapValue(xPos + 1, yPos + 2) + getMapValue(xPos + 5, yPos + 2) + getMapValue(xPos + 2, yPos + 4) + getMapValue(xPos + 4, yPos + 4) + getMapValue(xPos + 3, yPos + 5) <= -1){
            return 2;
        } else {
            setEnemyMap(xPos, yPos + 1, type);
            setEnemyMap(xPos + 6, yPos + 1, type);
            setEnemyMap(xPos + 1, yPos + 2, type);
            setEnemyMap(xPos + 5, yPos + 2, type);
            setEnemyMap(xPos + 2, yPos + 4, type);
            setEnemyMap(xPos + 4, yPos + 4, type);
            setEnemyMap(xPos + 3, yPos + 5, type);
            setEnemyMap(xPos + 3, yPos + 4, type);
            return 0;
        }
    }
    return 0;
}

//清除飞船某一位置
void clearCraftMap(int xPos, int yPos){
    if(xPos >= 83 || xPos < 0 || yPos < 0 || yPos >= 34){
        return;
    } else {
        if(gameMap[xPos][yPos] > 0){
            eraseText(enemyDestroyedSprite, 6, 7, enemies[gameMap[xPos][yPos] - 1].posX, enemies[gameMap[xPos][yPos] - 1].posY);
            applyDamage();
            enemies[gameMap[xPos][yPos] - 1].health = 0;
        }
    }
}

// 获取地图上某位置的值
int getMapValue(int xPos, int yPos){
    if(xPos >= 83 || xPos < 0 || yPos < 0 || yPos >= 34){
        return 0;
    } else {
        return gameMap[xPos][yPos];
    }
}

// 设置敌人在地图上的位置
void setEnemyMap(int xPos, int yPos, int type){
    if(xPos >= 83 || xPos < 0 || yPos < 0 || yPos >= 34){
        return;
    } else {
        gameMap[xPos][yPos] = type;
    }
}

// 清除飞船的左边缘
void clearLeftEdge(){
    renderCharacter(' ', craftX + 3, 28);
    renderCharacter(' ', craftX + 2, 29);
    renderCharacter(' ', craftX + 2, 30);
    renderCharacter(' ', craftX + 1, 31);
    renderCharacter(' ', craftX, 32);
    renderCharacter(' ', craftX + 1, 33);
    renderCharacter(' ', craftX + 4, 33);
}

// 清除飞船的右边缘
void clearRightEdge(){
    renderCharacter(' ', craftX + 3, 28);
    renderCharacter(' ', craftX + 4, 29);
    renderCharacter(' ', craftX + 4, 30);
    renderCharacter(' ', craftX + 5, 31);
    renderCharacter(' ', craftX + 6, 32);
    renderCharacter(' ', craftX + 5, 33);
    renderCharacter(' ', craftX + 2, 33);
}

// 显示准备消息
void displayReadyMessage(){
    setFontColor(3, 1);
    displaySlantText(readyScreenText, 47, 6, 32, 14, 2, 10000);
    usleep(1500000);
    eraseSlantText(47, 6, 32, 14, 2, 10000);
    displaySlantText(goScreenText,44, 6, 32, 14, 2, 10000);
    usleep(1000000);
    eraseSlantText(44, 6, 32, 14, 2, 10000);
}

// 终止游戏
void terminateGame(){
    eraseSlantText(110, 36, 0, 0, 5, 5000);
                    
    setFontColor(0, 1);
    sleep(1);
    echo();
    endwin();	
    exit(0);
}

// 验证窗口大小
void verifyWindowSize(){
    
}

// 验证终端颜色支持
void verifyColorSupport(){
    if(!has_colors()){
        endwin();
        printf("Your terminal does not support color\n");
        exit(1);
    } else {
        start_color();
    }
}

// 显示斜体文本动画
void displaySlantText(char * text, int width, int height, int x, int y, int step, int delay){
    int i, j, k;
    for(i = 1; i <= (width + step - 1) / step + height; i++){
        for(j = 0; j < ((height > i) ? i : height); j++){
            for(k = 0; k < step; k++){
                if(k + (i - j - 1) * step > width - 1) break;
                renderCharacter(*(text + k + (i - j - 1) * step + j * width), x + k + (i - j - 1) * step, y + j);
            }
            move(35, 95);
            refresh();
        }
        usleep(delay);
    }
}

// 删除斜体文本动画
void eraseSlantText(int width, int height, int x, int y, int step, int delay){
    int i, j, k;
    for(i = 1; i <= (width + step - 1) / step + height; i++){
        for(j = 0; j < ((height > i) ? i : height); j++){
            for(k = 0; k < step; k++){
                if(k + (i - j - 1) * step > width - 1) break;
                renderCharacter(' ', x + k + (i - j - 1) * step, y + j);
            }
            move(35, 95);
            refresh();
        }
        usleep(delay);
    }
}

// 在指定位置渲染一个字符
void renderCharacter(char c, int xPos, int yPos){
    move(yPos, xPos);
    printw("%c", c);
}

// 渲染游戏 Logo??
void renderLogo(){
    setFontColor(0, 1);
    usleep(1500000);
    eraseSlantText(40, 12, 27, 11, 2, 10000);
}

// 更新菜单选择
void updateMenuSelection(int selectionType){
    highlightMenuOption(menuChoice, 0);
    if(selectionType == 'w' || selectionType == 'W'){
        menuChoice = (menuChoice == 1) ? 6 : menuChoice - 1;
    } else if(selectionType == 's' || selectionType == 'S'){
        menuChoice = (menuChoice == 6) ? 1 : menuChoice + 1;
    }
    highlightMenuOption(menuChoice, 1);
}

// 设置字体颜色和样式
void setFontColor(int colorPair, int bold){
    if(bold == 1){
        attrset(COLOR_PAIR(colorPair) | A_BOLD);
    } else if(bold == 0){
        attrset(COLOR_PAIR(colorPair));
    }
}

// 高亮显示菜单选项
void highlightMenuOption(int option, int highlight){
    setFontColor(1, highlight);
    if(option == 1){
        mvprintw(23, 50,"    Single-player     ");
    } else if(option == 2){
        mvprintw(24,50,"    Matching Mode     ");
    } else if(option == 3){
        mvprintw(25,50,"    Create Room        ");
    } else if(option == 4){
        mvprintw(26,50,"     Join Room        ");
    }else if(option == 5){
        mvprintw(27,50,"      Log Out         ");
    }else if(option == 6){
        mvprintw(28,50,"     Exit Game        ");
    }
    if(highlight == 1){
        move(22 + option, 51);
        printw("->");
        move(22 + option, 67);
        printw("<-");		
    }
    moveCursorToCorner();
}

// 绘制主菜单
void drawMenu(){
    setFontColor(1, 1);     
    displaySlantText(gameTitle,62, 6, 35, 12, 3, 10000);
    usleep(80000);
    if(playerName[0] ==0){
        checkLoginStatus();
    }
    showUser();
    attroff(A_BOLD);
    highlightMenuOption(1, (menuChoice == 1) ? 1 : 0);
    highlightMenuOption(2, (menuChoice == 2) ? 1 : 0);
    highlightMenuOption(3, (menuChoice == 3) ? 1 : 0);
    highlightMenuOption(4, (menuChoice == 4) ? 1 : 0);
    highlightMenuOption(5, (menuChoice == 5) ? 1 : 0); // 新增选项
    highlightMenuOption(6, (menuChoice == 6) ? 1 : 0); // 新增选项
    moveCursorToCorner();
    refresh();
    while(1){
        currentKey = getch();
        mvprintw(35, 60, "                                    ");
        if(currentKey == 's' || currentKey == 'S' || currentKey == 'w' || currentKey == 'W'){
            updateMenuSelection(currentKey);
        } else if(currentKey == 10){
            executeMenu();
        }
    }
}

// 移动光标到屏幕角落
void moveCursorToCorner(){
    move(35, 75);
}

// 动画
void animateButton(char * text, int height, int width, int x, int y, int *delayTimes, int arraySize, int endPosition){
    int k, l;
    for(k = y; k < LINES; k++){
        if(endPosition == k){
            break;
        }
        for(l = x; l <= x + width - 1; l++){
            renderCharacter(' ', l, k - 1);
        }
        renderTextOnScreen(text, height, width, x, k);
        refresh();
        if(k - y >= arraySize){
            usleep(delayTimes[arraySize - 1]);
        } else {
            usleep(delayTimes[k - y]);
        }
    }
}

//在屏幕上渲染文本
void renderTextOnScreen(char * text, int height, int width, int x, int y){
    int i, j;
    for(i = 0; i < height; i++){
        if(x + i < 0){
            continue;
        }
        if(y + i >= 36){
            break;
        }
        for(j = 0; j < width; j++){
            renderCharacter(*(text + j + i * width), x + j, y + i);
            mvprintw(35, 95, "");
        }
    }
    moveCursorToCorner();
}

// 仅渲染非空格字符
void renderNonSpaceCharacters(char * text, int height, int width, int x, int y){
    int i, j;
    for(i = 0; i < height; i++){
        if(x + i < 0){
            continue;
        }
        if(y + i >= 34){
            break;
        }
        for(j = 0; j < width; j++){
            if(*(text + j + i * width) != ' '){
                renderCharacter(*(text + j + i * width), x + j, y + i);
            }
            moveCursorToCorner();
        }
    }
    moveCursorToCorner();
}

// 清除文本
void eraseText(char * text, int height, int width, int x, int y){
    int i, j;
    for(i = 0; i < height; i++){
        if(x + i < 0){
            continue;
        }
        if(y + i >= 34){
            break;
        }
        for(j = 0; j < width; j++){
            if(*(text + j + i * width) == '_'){
                renderCharacter(' ', x + j, y + i);
            }
            moveCursorToCorner();
        }
    }
    moveCursorToCorner();
}

// 主方法启动游戏
int main(){
    initscr();
    noecho();
    crmode();
    verifyWindowSize();
    verifyColorSupport();
    pthread_mutex_init(&writeLock, NULL);
    pthread_mutex_init(&clearLock, NULL);
    clear();
    // Initialize random number generator
    srand((unsigned)time(NULL));
    init_pair(0, COLOR_WHITE, COLOR_BLACK);
    init_pair(1, COLOR_YELLOW, COLOR_BLACK);
    init_pair(2, COLOR_BLUE, COLOR_BLACK);
    init_pair(3, COLOR_GREEN, COLOR_BLACK);
    init_pair(4, COLOR_RED, COLOR_BLACK);
    gameSemaphore = sem_open("gameSemaphore", O_CREAT, 0644, 0);
    sem_init(gameSemaphore, 0, 0);
    networkSemaphore = sem_open("networkSemaphore", O_CREAT, 0644, 0);
    sem_init(networkSemaphore, 0, 0);
    setFontColor(0, 0);
    renderLogo();
    sleep(1);
    drawMenu();
    endwin();
    return 0;
}
